﻿using System;

namespace UniRx
{
	// Token: 0x020001FF RID: 511
	public sealed class RefCountDisposable : ICancelable, IDisposable
	{
		// Token: 0x06000AC5 RID: 2757 RVA: 0x00039391 File Offset: 0x00037791
		public RefCountDisposable(IDisposable disposable)
		{
			if (disposable == null)
			{
				throw new ArgumentNullException("disposable");
			}
			this._disposable = disposable;
			this._isPrimaryDisposed = false;
			this._count = 0;
		}

		// Token: 0x170000DD RID: 221
		// (get) Token: 0x06000AC6 RID: 2758 RVA: 0x000393CA File Offset: 0x000377CA
		public bool IsDisposed
		{
			get
			{
				return this._disposable == null;
			}
		}

		// Token: 0x06000AC7 RID: 2759 RVA: 0x000393D8 File Offset: 0x000377D8
		public IDisposable GetDisposable()
		{
			object gate = this._gate;
			IDisposable result;
			lock (gate)
			{
				if (this._disposable == null)
				{
					result = Disposable.Empty;
				}
				else
				{
					this._count++;
					result = new RefCountDisposable.InnerDisposable(this);
				}
			}
			return result;
		}

		// Token: 0x06000AC8 RID: 2760 RVA: 0x0003943C File Offset: 0x0003783C
		public void Dispose()
		{
			IDisposable disposable = null;
			object gate = this._gate;
			lock (gate)
			{
				if (this._disposable != null && !this._isPrimaryDisposed)
				{
					this._isPrimaryDisposed = true;
					if (this._count == 0)
					{
						disposable = this._disposable;
						this._disposable = null;
					}
				}
			}
			if (disposable != null)
			{
				disposable.Dispose();
			}
		}

		// Token: 0x06000AC9 RID: 2761 RVA: 0x000394B8 File Offset: 0x000378B8
		private void Release()
		{
			IDisposable disposable = null;
			object gate = this._gate;
			lock (gate)
			{
				if (this._disposable != null)
				{
					this._count--;
					if (this._isPrimaryDisposed && this._count == 0)
					{
						disposable = this._disposable;
						this._disposable = null;
					}
				}
			}
			if (disposable != null)
			{
				disposable.Dispose();
			}
		}

		// Token: 0x040006F4 RID: 1780
		private readonly object _gate = new object();

		// Token: 0x040006F5 RID: 1781
		private IDisposable _disposable;

		// Token: 0x040006F6 RID: 1782
		private bool _isPrimaryDisposed;

		// Token: 0x040006F7 RID: 1783
		private int _count;

		// Token: 0x02000200 RID: 512
		private sealed class InnerDisposable : IDisposable
		{
			// Token: 0x06000ACA RID: 2762 RVA: 0x0003953C File Offset: 0x0003793C
			public InnerDisposable(RefCountDisposable parent)
			{
				this._parent = parent;
			}

			// Token: 0x06000ACB RID: 2763 RVA: 0x00039558 File Offset: 0x00037958
			public void Dispose()
			{
				object obj = this.parentLock;
				RefCountDisposable parent;
				lock (obj)
				{
					parent = this._parent;
					this._parent = null;
				}
				if (parent != null)
				{
					parent.Release();
				}
			}

			// Token: 0x040006F8 RID: 1784
			private RefCountDisposable _parent;

			// Token: 0x040006F9 RID: 1785
			private object parentLock = new object();
		}
	}
}
